﻿// <copyright file="MediaBrowseViewModel.cs" company="EffuEfface">
//      Copyright (c) Effu Efface Consulting  All rights reserved.
// </copyright>
// <author>Ryan R. Sites</author>

namespace TVersiPlay.MediaBrowse.ViewModels
{
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Windows.Input;
    using Microsoft.Practices.Prism.Commands;
    using Microsoft.Practices.Prism.Events;
    using TVersiPlay.Common;
    using TVersiPlay.Common.Enumerations;
    using TVersiPlay.Common.Interfaces;
    using TVersiPlay.DTO;
    using TVersiPlay.Events;
    using System;
    using System.Windows.Threading;

    public class MediaBrowseViewModel : IMediaBrowseViewModel
    {
        #region declarations

        private IEventAggregator eventAggregator;
        private IUPnPControlPointService upnpService;
        private INavigationService navigate;
        private Dispatcher dispatcher;

        private ICommand browseContainer;
        private ICommand selectedItemsChanged;

        private ObservableCollection<UPnPContainer> upnpContainers;
        private ObservableCollection<UPnPMedia> upnpMedia;

        private bool hasContainerResults;

        private UPnPMedia activeRecord;      

        #endregion //declarations

        #region constructors

        public MediaBrowseViewModel(IEventAggregator eventAggregator, IUPnPControlPointService upnpService, INavigationService navigate)
        {
            this.eventAggregator = eventAggregator;
            this.upnpService = upnpService;
            this.navigate = navigate;
            this.dispatcher = Dispatcher.CurrentDispatcher;

            this.browseContainer = new DelegateCommand<UPnPContainer>(this.OnBrowseContainer);
            this.selectedItemsChanged = new DelegateCommand(this.OnSelectedItemChanged);
            this.eventAggregator.GetEvent<BrowseResultEvent>().Subscribe(this.OnBrowseContainerComplete, ThreadOption.UIThread, false,
                x => x.OriginOfBrowse == BrowseOrigin.MainMenu || x.OriginOfBrowse == BrowseOrigin.MediaBrowse);

            this.upnpMedia = new ObservableCollection<UPnPMedia>();
            this.upnpContainers = new ObservableCollection<UPnPContainer>();
        }
            
        #endregion //constructors

        #region properties

        /// <summary>
        /// Gets or sets the type of browse.
        /// </summary>
        /// <value>The type of browse.</value>
        private BrowseType TypeOfBrowse { get; set; }

        /// <summary>
        /// Gets or sets the UpnP container results.
        /// </summary>
        /// <value>The UpnP container results.</value>
        public ObservableCollection<UPnPContainer> UPnPContainerResults
        {
            get
            {
                return this.upnpContainers;
            }
            set
            {
                this.upnpContainers = value;
                this.OnPropertyChanged("UPnPContainerResults");
            }
        }

        /// <summary>
        /// Gets or sets the U pn P media results.
        /// </summary>
        /// <value>The U pn P media results.</value>
        public ObservableCollection<UPnPMedia> UPnPMediaResults
        {
            get
            {
                return this.upnpMedia;
            }
            set
            {
                this.upnpMedia = value;
                this.OnPropertyChanged("UPnPMediaResults");
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance has container results.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance has container results; otherwise, <c>false</c>.
        /// </value>
        public bool HasContainerResults
        {
            get
            {
                return this.hasContainerResults;
            }
            set
            {
                this.hasContainerResults = value;
                this.OnPropertyChanged("HasContainerResults");
            }
        }

        /// <summary>
        /// Gets or sets the active record.
        /// </summary>
        /// <value>The active record.</value>
        public UPnPMedia ActiveRecord
        {
            get
            {
                return this.activeRecord;
            }
            set
            {
                this.activeRecord = value;
                this.OnPropertyChanged("ActiveRecord");
            }
        }

        /// <summary>
        /// Gets the browse container.
        /// </summary>
        /// <value>The browse container.</value>
        public ICommand BrowseContainer
        {
            get { return this.browseContainer; }
        }

        /// <summary>
        /// Gets the items changed.
        /// </summary>
        /// <value>The items changed.</value>
        public ICommand ItemsChanged
        {
            get { return this.selectedItemsChanged; }
        }

        #endregion //properties

        #region methods

        private void OnBrowseContainer(UPnPContainer containerToBrowse)
        {
            if (containerToBrowse != null)
            {
                if (containerToBrowse.ContainerType == "Main Menu")
                    this.navigate.NavigateViewToRegion(ViewNames.MainMenuView, RegionNames.MainRegion);
                else
                {
                    this.eventAggregator.GetEvent<LongRunningProcessEvent>().Publish(new DTO.LongRunningProcess() { BusyMessage = "Getting data from media server", IsBusy = true, ShowPopUp = true });
                    this.upnpService.BrowseMediaServer(this.TypeOfBrowse, containerToBrowse.ContainerId, Common.ContentDirectory.Enum_A_ARG_TYPE_BrowseFlag.BROWSEDIRECTCHILDREN, this.OnBrowseContainerComplete);
                }         
            }
        }

        private void OnBrowseContainerComplete(DTO.BrowseResults results)
        {
            this.eventAggregator.GetEvent<LongRunningProcessEvent>().Publish(new DTO.LongRunningProcess(){IsBusy = false});

            //if (!this.dispatcher.CheckAccess())
            //{
            //    this.dispatcher.BeginInvoke(new Action<DTO.BrowseResults>((br) =>
            //    {
            //        this.ProcessResults(br);
            //    }), DispatcherPriority.Background, results);
            //}
            //else
            //    this.ProcessResults(results);


            this.ProcessResults(results);

           
                
        }

        private void OnSelectedItemChanged()
        {

        }

        private void OnUPnPBrowseResult(DTO.BrowseResults browseResults)
        {
            ProcessResults(browseResults);
        }

        private void ProcessResults(DTO.BrowseResults browseResults)
        {

            Action<DTO.BrowseResults> processTheResults = (br) =>
            {

                this.UPnPMediaResults.Clear();
                this.UPnPContainerResults.Clear();

                if (browseResults != null)
                {
                    this.TypeOfBrowse = browseResults.TypeOfBrowse;

                    if (browseResults.ContainerResults != null)
                    {
                        this.HasContainerResults = browseResults.ContainerResults.Count > 0;
                        foreach (var e in browseResults.ContainerResults)
                        {
                            this.upnpContainers.Add(e);
                        }
                    }

                    if (browseResults.MediaResults != null && browseResults.MediaResults.Count > 0)
                    {                       

                        switch (browseResults.TypeOfBrowse)
                        {
                            case BrowseType.Audio:
                                {
                                    if (browseResults.MediaResults.Count == 1 || browseResults.MediaResults.Count == 2)
                                    {
                                        this.navigate.NavigateViewToRegion(ViewNames.OneOrTwoMusicView, RegionNames.BrowseResultsRegion);
                                        break;
                                    }
                                    else
                                    {
                                        this.navigate.NavigateViewToRegion(ViewNames.OneOrTwoMusicView, RegionNames.BrowseResultsRegion);
                                        break;
                                    }
                                }

                            case BrowseType.Internet:
                                break;
                            case BrowseType.Photo:
                                break;
                            case BrowseType.Video:
                                break;
                            case BrowseType.Root:
                                break;
                        }
                    }
                }


                foreach (var e in browseResults.MediaResults)
                {
                    this.upnpMedia.Add(e);
                }

                this.OnPropertyChanged("UPnPContainerResults");
                this.OnPropertyChanged("UPnPMediaResults");
            };


            if (!this.dispatcher.CheckAccess())
                this.dispatcher.BeginInvoke(processTheResults, DispatcherPriority.Background, browseResults);
            else
                processTheResults(browseResults);          
           
        }

        #endregion //methods

        #region events
        #endregion //events

        #region INotifyPropertyChanged Items

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler Handler = PropertyChanged;
            if (Handler != null)
                Handler(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }
}
